home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 6 / develop 6 code / TCP / NewsWatcher / NewsWatcher 2.0d15 source / source / ldef.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-17  |  8.3 KB  |  324 lines  |  [TEXT/KAHL]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     ldef.c
  4.  
  5.     This module contains the LDEF for NewsWatcher.
  6.     
  7.     Portions copyright © 1990, Apple Computer.
  8.     Portions copyright © 1993, Northwestern University.
  9.  
  10. ----------------------------------------------------------------------------*/
  11.  
  12. #include <string.h>
  13.  
  14. #include "glob.h"
  15. #include "ldef.h"
  16. #include "util.h"
  17.  
  18.  
  19. static RGBColor gHighlightColors[5] = {            /* hilight color table */
  20.     {0xDDDD, 0x0000, 0x0000},    /* red */
  21.     {0x0000, 0x9999, 0x0000},    /* green */
  22.     {0x0000, 0x0000, 0xDDDD},    /* blue */
  23.     {0x9999, 0x0000, 0x9999},    /* purple */
  24.     {0xDDDD, 0x7777, 0x0000},    /* orange */
  25. };
  26.  
  27. static RGBColor gLightBlue = {0x9999, 0x9999, 0xFFFF};    /* light blue for filling triangles */
  28.  
  29. static Rect *gRect;                    /* cell rect */
  30. static FontInfo gFontInfo;            /* font information */
  31. static TWindow **gInfo;                /* window information */
  32. static short gIndex;                /* index in group or subject array */
  33. static Handle gStrings;                /* handle to strings */
  34. static short gH, gV;                /* h and v coords for drawing */
  35. static Rect gEraseRect;                /* rectangle erased and redrawn */
  36. static TSubject **gSubjectArray;     /* handle to subject array */
  37. static TSubject gTheSubject;        /* subject record to be drawn */
  38.  
  39.  
  40.  
  41. /*----------------------------------------------------------------------------
  42.     DrawFullOrNewGroupCell
  43.     
  44.     Draws a single cell in the full group list window or the new groups
  45.     list window.
  46. ----------------------------------------------------------------------------*/
  47.  
  48. static void DrawFullOrNewGroupCell (void)
  49. {            
  50.     TGroup **groupArray;
  51.     char *theString;
  52.     short strLen;
  53.  
  54.     groupArray = (**gInfo).groupArray;
  55.     gEraseRect = *gRect;
  56.     EraseRect(&gEraseRect);
  57.     theString = *gStrings + (*groupArray)[gIndex].nameOffset;
  58.     strLen = strlen(theString);
  59.     MoveTo(gH, gV);
  60.     DrawText(theString, 0, strLen);
  61. }
  62.  
  63.  
  64.  
  65. /*----------------------------------------------------------------------------
  66.     DrawUserGroupCell
  67.     
  68.     Draws a single cell in a user group list window.
  69. ----------------------------------------------------------------------------*/
  70.  
  71. static void DrawUserGroupCell (void)
  72. {            
  73.     TGroup **groupArray, theGroup;
  74.     long numUnread;
  75.     char *theString;
  76.     short strLen;
  77.     Str255 numStr;
  78.  
  79.     groupArray = (**gInfo).groupArray;
  80.     theGroup = (*groupArray)[gIndex];
  81.     gEraseRect = *gRect;
  82.     if (theGroup.onlyRedrawCount) gEraseRect.right = gH + (**gInfo).numUnreadHCoord;
  83.     EraseRect(&gEraseRect);
  84.     numUnread = theGroup.numUnread;
  85.     if (numUnread != 0) {
  86.         if (numUnread > 9999) numUnread = 9999;
  87.         NumToString(numUnread, numStr);
  88.         MoveTo(gH + (**gInfo).numUnreadHCoord - StringWidth(numStr), gV);
  89.         DrawString(numStr);
  90.     }
  91.     if (!theGroup.onlyRedrawCount) {
  92.         theString = *gStrings + theGroup.nameOffset;
  93.         strLen = strlen(theString);
  94.         MoveTo(gH + (**gInfo).groupNameHCoord, gV);
  95.         DrawText(theString, 0, strLen);
  96.     }
  97. }
  98.  
  99.  
  100.  
  101. /*----------------------------------------------------------------------------
  102.     DrawThreadHeadInfo
  103.     
  104.     Draws the thread head info for a thread head cell in a subject list 
  105.     window (the thread control and number of articles in the thread).
  106. ----------------------------------------------------------------------------*/
  107.  
  108. static void DrawThreadHeadInfo (void)
  109. {
  110.     PolyHandle poly;
  111.     short th, tv;
  112.     Str255 numStr;
  113.     short threadLength;
  114.     RGBColor saveFG;
  115.     Rect tempRect;
  116.  
  117.     if (gTheSubject.threadLength == 1) {
  118.         MoveTo(gH + (**gInfo).minusSignHCoord, gV);
  119.         DrawChar('-');
  120.     } else {
  121.         if (gTheSubject.collapsed) {
  122.             poly = (**gInfo).collapseTriangle;
  123.             th = gH + ((**poly).polyBBox.right >> 1) + 1; 
  124.             tv = gRect->top + 1;
  125.         } else {
  126.             poly = (**gInfo).expandTriangle;
  127.             th = gH + 1; 
  128.             tv = gRect->top + ((**poly).polyBBox.bottom >> 1) + 1;
  129.         }
  130.         OffsetPoly(poly, th, tv);
  131.         if (gTheSubject.drawTriangleFilled) {
  132.             FillPoly(poly, qd.black);
  133.         } else {
  134.             tempRect = (**poly).polyBBox;
  135.             if (GetPixelDepth(&tempRect) > 2) {
  136.                 GetForeColor(&saveFG);
  137.                 RGBForeColor(&gLightBlue);
  138.                 FillPoly(poly, qd.gray);
  139.                 RGBForeColor(&saveFG);
  140.             }
  141.         }
  142.         FramePoly(poly);
  143.         OffsetPoly(poly, -th, -tv);
  144.  
  145.         if (!gTheSubject.onlyRedrawTriangle) {
  146.             threadLength = gTheSubject.threadLength;
  147.             if (threadLength > 99) threadLength = 99;
  148.             NumToString(threadLength, numStr);
  149.             MoveTo(gH + (**gInfo).threadCountHCoord - StringWidth(numStr), gV);
  150.             DrawString(numStr);
  151.         }
  152.     }
  153. }
  154.  
  155.  
  156.  
  157. /*----------------------------------------------------------------------------
  158.     DrawCheckMark
  159.     
  160.     Draws the article read check mark in a cell in a subject list window.
  161.     For collapsed thread head cells, the mark is drawn iff the entire
  162.     thread has been read. 
  163. ----------------------------------------------------------------------------*/
  164.  
  165. static void DrawCheckMark (void)
  166. {
  167.     Boolean read;
  168.     short nextInThread;
  169.  
  170.     if (gTheSubject.collapsed) {
  171.         read = true;
  172.         nextInThread = gIndex;
  173.         while (true) {
  174.             if (!(*gSubjectArray)[nextInThread].read) {
  175.                 read = false;
  176.                 break;
  177.             }
  178.             nextInThread = 
  179.                 (*gSubjectArray)[nextInThread].nextInThread;
  180.             if (nextInThread == -1) break;
  181.         }
  182.     } else {
  183.         read = gTheSubject.read;
  184.     }
  185.     if (read) {
  186.         MoveTo(gH + (**gInfo).checkHCoord, gV);
  187.         DrawChar('√');
  188.     }
  189. }
  190.  
  191.  
  192.  
  193. /*----------------------------------------------------------------------------
  194.     DrawAuthorAndSubject
  195.     
  196.     Draws the author and subject in a cell in a subject list window.
  197. ----------------------------------------------------------------------------*/
  198.  
  199. static void DrawAuthorAndSubject (void)
  200. {
  201.     RGBColor saveFG;
  202.     char *theString;
  203.     short strLen;
  204.     short width;
  205.  
  206.     if (gHasColorQD && gTheSubject.highlight > 0) {
  207.         GetForeColor(&saveFG);
  208.         RGBForeColor(&gHighlightColors[gTheSubject.highlight-1]);
  209.     }
  210.     if ((**gInfo).authorsShown && gTheSubject.authorOffset >= 0) {
  211.         theString = *gStrings + gTheSubject.authorOffset;
  212.         strLen = strlen(theString);
  213.         while (true) {
  214.             width = TextWidth(theString, 0, strLen);
  215.             if (width <= (**gInfo).authorWidth) break;
  216.             if (strLen == 1) break;
  217.             strLen--;
  218.         }
  219.         MoveTo(gH + (**gInfo).authorHCoord, gV);
  220.         DrawText(theString, 0, strLen);
  221.     }
  222.     theString = *gStrings + gTheSubject.subjectOffset;
  223.     strLen = strlen(theString);
  224.     MoveTo(gH + (**gInfo).subjectHCoord, gV);
  225.     DrawText(theString, 0, strLen);
  226.     if (gHasColorQD && gTheSubject.highlight > 0) {
  227.         RGBForeColor(&saveFG);
  228.     }
  229. }
  230.  
  231.  
  232.  
  233. /*----------------------------------------------------------------------------
  234.     DrawSubjectCell
  235.     
  236.     Draws a single cell in a subject list window.
  237. ----------------------------------------------------------------------------*/
  238.  
  239. static void DrawSubjectCell (void)
  240. {    
  241.     gSubjectArray = (**gInfo).subjectArray;
  242.     gTheSubject = (*gSubjectArray)[gIndex];
  243.     gEraseRect = *gRect;
  244.     if (gTheSubject.onlyRedrawTriangle) {
  245.         gEraseRect.right = gH + gFontInfo.ascent + 2;
  246.     } else if (gTheSubject.onlyRedrawCheck) {
  247.         gEraseRect.left = gH + (**gInfo).checkHCoord;
  248.         gEraseRect.right = gH + (**gInfo).authorHCoord;
  249.     }
  250.     EraseRect(&gEraseRect);
  251.     
  252.     if (gTheSubject.threadOrdinal == 1 && !gTheSubject.onlyRedrawCheck) 
  253.         DrawThreadHeadInfo();
  254.     
  255.     if (!gTheSubject.onlyRedrawTriangle) 
  256.         DrawCheckMark();
  257.         
  258.     if (!gTheSubject.onlyRedrawTriangle && !gTheSubject.onlyRedrawCheck) 
  259.         DrawAuthorAndSubject();
  260. }
  261.  
  262.  
  263.  
  264. /*----------------------------------------------------------------------------
  265.     ListDefFunc
  266.     
  267.     This is the list definition function used for group and subject list 
  268.     windows. It is called by the stub code in the standalone LDEF 128 code 
  269.     resource.
  270. ----------------------------------------------------------------------------*/
  271.  
  272. void ListDefFunc (short lMessage, Boolean lSelect, Rect *lRect, Cell lCell,
  273.     short lDataOffset, short lDataLen, ListHandle lHandle)
  274. {    
  275.     char *cellDataPtr;
  276.     EWindowKind kind;
  277.     
  278.     switch (lMessage) {
  279.  
  280.       case lDrawMsg:
  281.       
  282.         (**lHandle).port->txFace = 0;
  283.         GetFontInfo(&gFontInfo);
  284.         gRect = lRect;
  285.         gH = lRect->left + (**lHandle).indent.h;
  286.         gV = lRect->top + gFontInfo.ascent;
  287.         gInfo = (TWindow**)GetWRefCon((WindowPtr)(**lHandle).port);
  288.         kind = (**gInfo).kind;
  289.         gStrings = (**gInfo).strings;
  290.         cellDataPtr = *(**lHandle).cells + lDataOffset;
  291.         gIndex = *(unsigned short*)cellDataPtr;
  292.         
  293.         HLock(gStrings);
  294.         switch (kind) {
  295.             case kFullGroup:
  296.             case kNewGroup:
  297.                 DrawFullOrNewGroupCell();
  298.                 break;
  299.             case kUserGroup:
  300.                 DrawUserGroupCell();
  301.                 break;
  302.             case kSubject:
  303.                 DrawSubjectCell();
  304.                 break;
  305.         }
  306.         HUnlock(gStrings);
  307.  
  308.         if (lSelect) {
  309.             BitClr(&HiliteMode, pHiliteBit);
  310.             InvertRect(&gEraseRect);
  311.         }
  312.         
  313.           break;
  314.  
  315.       case lHiliteMsg:
  316.       
  317.         BitClr(&HiliteMode, pHiliteBit);
  318.           InvertRect(lRect);
  319.           break;
  320.           
  321.     }
  322.     
  323. }
  324.